from bs4 import BeautifulSoup
import re
from .base import Handler
from event_engine.event_type import *
from event_engine.event import Event
from event_engine.engine import EventEngine
from models.task import *
from models.house import HOUSE_TYPE_RENT_DEFAULT, HOUSE_TYPE_RENT_APARTMENT

area_re = re.compile(r'([\d\.\-]*)㎡')
room_re = re.compile(r'(\d*)室(\d*)厅')
page_re = re.compile(r'\/pg\d+\/')
community_re = re.compile(r'\/c(\d+)')


class RentListHandler(Handler):
    """
    租房列表
    """

    def process(self, event: Event, engine: EventEngine) -> None:
        html: str = event.data["html"]
        task: Task = event.data["task"]
        try:
            soup = BeautifulSoup(html, 'html.parser')
            self.parse_page(soup, task, engine)
            self.parse_house(soup, engine)
            task.complete()
        except Exception as e:
            print(e)

    def parse_page(self, soup: any, task: Task, engine: EventEngine):
        """
        解析列表页分页
        :param soup: BeautifulSoup对象
        :param task: 任务
        :param engine: 事件引擎实例
        :return:
        """
        is_first_page = False if page_re.search(task.url) else True
        if is_first_page:
            page = soup.find("div", "content__pg")
            if not page:
                return
            total_page = page.attrs["data-totalpage"]
            for i in range(int(total_page)):
                if i > 0:
                    url: str = "%spg%s/" % (task.url, i + 1)
                    engine.put(Event(EVENT_SAVE_TASK, {
                        "type": TYPE_RENT_LIST,
                        "url": url,
                        "referer": task.url,
                    }))

    def parse_house(self, soup: any, engine: EventEngine):
        """
        解析房屋信息
        :param soup: BeautifulSoup对象
        :param engine: 事件引擎实例
        :return:
        """
        city = soup.title.text[0:2]
        uls = soup.find_all("ul", attrs={"data-target": "area"})
        a = uls[0].find("li", "strong").find("a")
        district = a.text
        a = uls[1].find("li", "strong").find("a")
        circle = a.text
        house_list = soup.find_all("div", attrs={"class": "content__list--item", "data-house_code": True})
        for item in house_list:
            house_code = item.attrs["data-house_code"]
            des = item.find("p", "content__list--item--des")
            a_list = des.find_all("a")
            if len(a_list) == 3:
                a = a_list[-1]
                name = a.text
                ret = community_re.search(a.attrs['href'])
                if ret:
                    community_code = ret.group(1)
                    house_type = HOUSE_TYPE_RENT_DEFAULT
                else:
                    community_code = ""
                    house_type = HOUSE_TYPE_RENT_APARTMENT
            else:
                p = item.find("p", "content__list--item--brand")
                name = p.text.strip()
                community_code = ""
                house_type = HOUSE_TYPE_RENT_APARTMENT
            price_str = item.find("span", "content__list--item-price").find("em").text
            ret = price_str.split("-")
            if "" == ret[0]:
                continue
            price = int(ret[0]) if len(ret) == 1 else int((int(ret[1]) + int(ret[0])) / 2)
            ret = area_re.search(des.text)
            if ret:
                area_str = ret.group(1)
                area_range = area_str.split("-")
                if "" == area_range[0]:
                    continue
                area = int(area_range[0]) if len(area_range) == 1 else int(
                    (int(area_range[1]) + int(area_range[0])) / 2)
            else:
                area = 0
            ret = room_re.search(des.text)
            if ret:
                bedroom = ret.group(1)
                sitting_room = ret.group(2)
            else:
                bedroom = 0
                sitting_room = 0

            engine.put(Event(EVENT_SAVE_HOUSE, {
                "type": house_type,
                "community_code": community_code,
                "house_code": house_code,
                "name": name,
                "city": city,
                "district": district,
                "circle": circle,
                "price": price,
                "area": area,
                "bedroom": bedroom,
                "sitting_room": sitting_room,
            }))
